using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;

namespace Sensor.UI.Utils;

/// <summary>
/// 数据流控制器，防止数据丢失并控制数据流速率
/// </summary>
public class DataFlowController : IDisposable
{
    private readonly RingBuffer<string> _buffer;
    private readonly SemaphoreSlim _processingLock = new(1, 1);
    private readonly Timer _flowControlTimer;
    private readonly CancellationTokenSource _cancellationTokenSource = new();
    private bool _disposedValue = false;
    
    // 流控配置
    private readonly int _maxBufferSize;
    private readonly TimeSpan _maxBufferAge = TimeSpan.FromSeconds(5);
    private readonly int _targetProcessingRate; // 每秒目标处理数量
    private int _currentProcessingRate;
    private DateTime _lastFlowAdjustment = DateTime.UtcNow;
    
    // 性能计数器
    private long _totalReceived = 0;
    private long _totalProcessed = 0;
    private long _totalDropped = 0;
    private long _bufferOverflows = 0;
    
    public int BufferCount => _buffer.Count;
    public int CurrentProcessingRate => _currentProcessingRate;
    public long TotalReceived => _totalReceived;
    public long TotalProcessed => _totalProcessed;
    public long TotalDropped => _totalDropped;
    public long BufferOverflows => _bufferOverflows;
    
    // 事件
    public event Action<string>? OnDataReady;
    public event Action<FlowControlStats>? OnStatsUpdated;
    
    public DataFlowController(int bufferSize = 2000, int targetRate = 20)
    {
        _maxBufferSize = bufferSize;
        _targetProcessingRate = targetRate;
        _currentProcessingRate = targetRate;
        _buffer = new RingBuffer<string>(bufferSize);
        
        // 设置流控定时器，每秒调整一次处理速率
        _flowControlTimer = new Timer(AdjustFlowControl, null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
    }
    
    /// <summary>
    /// 添加数据到缓冲区
    /// </summary>
    /// <param name="data">要添加的数据</param>
    /// <returns>是否成功添加（false表示缓冲区已满）</returns>
    public bool TryAddData(string data)
    {
        if (_disposedValue || string.IsNullOrEmpty(data))
            return false;
            
        Interlocked.Increment(ref _totalReceived);
        
        // 尝试添加到缓冲区
        if (_buffer.TryAdd(data))
        {
            // 如果有处理线程空闲，触发处理
            if (_processingLock.Wait(0))
            {
                Task.Run(ProcessBufferAsync, _cancellationTokenSource.Token);
            }
            return true;
        }
        else
        {
            // 缓冲区已满，记录丢弃
            Interlocked.Increment(ref _totalDropped);
            Interlocked.Increment(ref _bufferOverflows);
            
            // 尝试强制处理一些数据以释放空间
            if (_processingLock.Wait(0))
            {
                Task.Run(ProcessBufferAsync, _cancellationTokenSource.Token);
            }
            return false;
        }
    }
    
    /// <summary>
    /// 异步处理缓冲区数据
    /// </summary>
    private async Task ProcessBufferAsync()
    {
        try
        {
            var processedCount = 0;
            var targetBatchSize = Math.Max(1, _currentProcessingRate / 10); // 每次处理1/10秒的数据量
            
            // 批量处理数据
            while (processedCount < targetBatchSize && _buffer.TryTake(out string? data))
            {
                OnDataReady?.Invoke(data);
                Interlocked.Increment(ref _totalProcessed);
                processedCount++;
                
                // 控制处理速率
                if (processedCount % 10 == 0) // 每处理10个数据点检查一次
                {
                    await Task.Delay(1, _cancellationTokenSource.Token).ConfigureAwait(false);
                }
            }
        }
        catch (OperationCanceledException)
        {
            // 正常取消，不需要处理
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine($"数据流处理错误: {ex.Message}");
        }
        finally
        {
            _processingLock.Release();
        }
    }
    
    /// <summary>
    /// 调整流控参数
    /// </summary>
    private void AdjustFlowControl(object? state)
    {
        if (_disposedValue)
            return;
            
        var now = DateTime.UtcNow;
        var timeSinceLastAdjustment = now - _lastFlowAdjustment;
        
        if (timeSinceLastAdjustment < TimeSpan.FromSeconds(1))
            return;
            
        _lastFlowAdjustment = now;
        
        // 计算缓冲区使用率
        var bufferUsageRatio = (double)_buffer.Count / _maxBufferSize;
        
        // 动态调整处理速率
        if (bufferUsageRatio > 0.8) // 缓冲区使用率过高，增加处理速率
        {
            _currentProcessingRate = Math.Min(_targetProcessingRate * 2, _currentProcessingRate + 5);
        }
        else if (bufferUsageRatio < 0.2) // 缓冲区使用率过低，减少处理速率
        {
            _currentProcessingRate = Math.Max(_targetProcessingRate / 2, _currentProcessingRate - 2);
        }
        else // 缓冲区使用率适中，恢复到目标速率
        {
            _currentProcessingRate = _targetProcessingRate;
        }
        
        // 清理过期数据
        CleanExpiredData();
        
        // 触发统计更新事件
        OnStatsUpdated?.Invoke(new FlowControlStats
        {
            BufferCount = _buffer.Count,
            CurrentProcessingRate = _currentProcessingRate,
            TotalReceived = _totalReceived,
            TotalProcessed = _totalProcessed,
            TotalDropped = _totalDropped,
            BufferOverflows = _bufferOverflows,
            BufferUsageRatio = bufferUsageRatio
        });
    }
    
    /// <summary>
    /// 清理过期数据
    /// </summary>
    private void CleanExpiredData()
    {
        // 简化实现：如果缓冲区使用率过高，丢弃一些旧数据
        if (_buffer.Count > _maxBufferSize * 0.9)
        {
            var dropCount = _buffer.Count / 10; // 丢弃10%的数据
            for (int i = 0; i < dropCount && _buffer.TryTake(out _); i++)
            {
                Interlocked.Increment(ref _totalDropped);
            }
        }
    }
    
    /// <summary>
    /// 获取当前状态信息
    /// </summary>
    public FlowControlStats GetCurrentStats()
    {
        return new FlowControlStats
        {
            BufferCount = _buffer.Count,
            CurrentProcessingRate = _currentProcessingRate,
            TotalReceived = _totalReceived,
            TotalProcessed = _totalProcessed,
            TotalDropped = _totalDropped,
            BufferOverflows = _bufferOverflows,
            BufferUsageRatio = (double)_buffer.Count / _maxBufferSize
        };
    }
    
    /// <summary>
    /// 重置统计计数器
    /// </summary>
    public void ResetStats()
    {
        Interlocked.Exchange(ref _totalReceived, 0);
        Interlocked.Exchange(ref _totalProcessed, 0);
        Interlocked.Exchange(ref _totalDropped, 0);
        Interlocked.Exchange(ref _bufferOverflows, 0);
    }
    
    #region IDisposable实现
    protected virtual void Dispose(bool disposing)
    {
        if (!_disposedValue)
        {
            if (disposing)
            {
                _cancellationTokenSource.Cancel();
                _flowControlTimer?.Dispose();
                _processingLock.Dispose();
                _buffer?.Clear();
            }
            _disposedValue = true;
        }
    }
    
    public void Dispose()
    {
        Dispose(disposing: true);
        GC.SuppressFinalize(this);
    }
    #endregion
}

/// <summary>
/// 流控统计信息
/// </summary>
public class FlowControlStats
{
    public int BufferCount { get; set; }
    public int CurrentProcessingRate { get; set; }
    public long TotalReceived { get; set; }
    public long TotalProcessed { get; set; }
    public long TotalDropped { get; set; }
    public long BufferOverflows { get; set; }
    public double BufferUsageRatio { get; set; }
    
    public override string ToString()
    {
        return $"缓冲区: {BufferCount}/{(int)(BufferUsageRatio * 100)}%, " +
               $"处理速率: {CurrentProcessingRate}/s, " +
               $"接收: {TotalReceived}, 处理: {TotalProcessed}, 丢弃: {TotalDropped}, " +
               $"溢出: {BufferOverflows}";
    }
}